package com.fy.utils.email;



import com.fy.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.annotation.Resource;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.File;
import java.security.Security;
import java.util.Date;
import java.util.Objects;
import java.util.Properties;

@Slf4j
@Component
public class EmailUtil {

    @Resource
    private JavaMailSender javaMailSender;

    private static EmailUtil INSTANCE;

    public EmailUtil() {
        INSTANCE = this;
    }

    public static EmailUtil getInstance(){
        return INSTANCE;
    }

    /**
     * 发送一封简单的文本文件
     * @param emailBean 文件内容
     * @return
     */
    public Result sendSimpleMail(EmailBean emailBean) {
        log.info("==开始发送邮件, Subject: {}, setTo:{}", emailBean.getSubject(), emailBean.getToEmail());
        SimpleMailMessage message = new SimpleMailMessage();
        //发件人
        message.setFrom(emailBean.getFromEmail());
        //收件人
        message.setTo(emailBean.getToEmail());
        //主题
        message.setSubject(emailBean.getSubject());
        //内容
        message.setText(emailBean.getText());
        try {
            javaMailSender.send(message);
            log.info("==邮件发送成功, Subject: {}, setTo:{}", emailBean.getSubject(), emailBean.getToEmail());
            return Result.ok();
        } catch (Exception e) {
            log.error("==邮件发送失败", e);
            return Result.error("邮件发送失败");
        }
    }

    public Result sendMailSSL(String fileDir,String to,String title,String content,String fileName){
        try{
            Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
            final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
            //设置邮件会话参数
            Properties props = new Properties();
            //邮箱的发送服务器地址
            props.setProperty("mail.smtp.host", "smtp.163.com");
            props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
            props.setProperty("mail.smtp.socketFactory.fallback", "false");
            props.put("mail.smtp.ssl.enable", true);
            //邮箱发送服务器端口,这里设置为465端口
            props.setProperty("mail.smtp.port", "465");
            props.setProperty("mail.smtp.socketFactory.port", "465");
            props.put("mail.smtp.auth", "true");
            final String username = "ww_today@163.com";
            final String password = "QBXCJWEGHELGUPQH";
            //获取到邮箱会话,利用匿名内部类的方式,将发送者邮箱用户名和密码授权给jvm
            Session session = Session.getDefaultInstance(props, new Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            });
            MimeMessage message =new MimeMessage(session);

            message.setFrom(new InternetAddress("ww_today@163.com","心理测评","UTF-8"));

            message.setRecipient(MimeMessage.RecipientType.TO,new InternetAddress(to,"xiuhong","UTF-8"));

            message.setSubject(title,"UTF-8");

            MimeMultipart multipart =new MimeMultipart();
            //读取本地图片,将图片数据添加到"节点"
            MimeBodyPart image =new MimeBodyPart();
            image.setFileName(fileName);
            DataHandler dataHandler1 =new DataHandler(new FileDataSource(fileDir));
            image.setDataHandler(dataHandler1);
            image.setContentID("image_suo");

            //创建文本节点
            MimeBodyPart text =new MimeBodyPart();
            text.setContent(content,"text/html;charset=UTF-8");

            //将文本和图片添加到multipart
            multipart.addBodyPart(text);
            multipart.addBodyPart(image);
            multipart.setSubType("related");//关联关系

            message.setContent(multipart);

            message.setSentDate(new Date());
            message.saveChanges();
            Transport.send(message);

            System.out.println("sendMailServlet-----end2");
            return  Result.ok("发送成功");
        }catch (Exception e){
            e.printStackTrace();
            return Result.error("发送失败");
        }
    }

    public static void main(String[] args) throws Exception {
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
        //设置邮件会话参数
        Properties props = new Properties();
        //邮箱的发送服务器地址
        props.setProperty("mail.smtp.host", "smtp.163.com");
        props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
        props.setProperty("mail.smtp.socketFactory.fallback", "false");
        //邮箱发送服务器端口,这里设置为465端口
        props.setProperty("mail.smtp.port", "465");
        props.setProperty("mail.smtp.socketFactory.port", "465");
        props.put("mail.smtp.auth", "true");
        final String username = "ww_today@163.com";
        final String password = "QBXCJWEGHELGUPQH";
        //获取到邮箱会话,利用匿名内部类的方式,将发送者邮箱用户名和密码授权给jvm
        Session session = Session.getDefaultInstance(props, new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });
        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress("ww_today@163.com"));
        message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("1006310522@qq.com", false));
        MimeMultipart multipart =new MimeMultipart();
        //读取本地图片,将图片数据添加到"节点"
        MimeBodyPart image =new MimeBodyPart();
        DataHandler dataHandler1 =new DataHandler(new FileDataSource("C:\\Users\\SLM\\Desktop\\20210731232837.png"));
        image.setDataHandler(dataHandler1);
        image.setContentID("image_suo");

        //创建文本节点
        MimeBodyPart text =new MimeBodyPart();
        text.setContent("数据库备份","text/html;charset=UTF-8");

        //将文本和图片添加到multipart
        multipart.addBodyPart(text);
        multipart.addBodyPart(image);
        multipart.setSubType("related");//关联关系

        message.setContent(multipart);

        message.setSentDate(new Date());
        message.saveChanges();
        Transport.send(message);

        System.out.println("sendMailServlet-----end2");
    }


    /**
     * 发送一封带附件的邮件
     * @param emailBean 文件内容
     * @return
     */
    public Result sendAttachmentsMail(EmailBean emailBean) {
        log.info("==开始发送邮件, Subject: {}, setTo:{}", emailBean.getSubject(), emailBean.getToEmail());
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper helper;
        try {
            helper = new MimeMessageHelper(mimeMessage, true);
            helper.setFrom(emailBean.getFromEmail());
            helper.setTo(emailBean.getToEmail());
            helper.setSubject(emailBean.getSubject());
            helper.setText(emailBean.getText());
            if (!CollectionUtils.isEmpty(emailBean.getEmailAttachment())) {
                emailBean.getEmailAttachment().stream().filter(Objects::nonNull).forEach(bean -> {
                    FileSystemResource file = new FileSystemResource(new File(bean.getFilePath()));
                    try {
                        helper.addAttachment(bean.getFileName(), file);
                    } catch (MessagingException e) {
                        log.error("==添加附件失败, filename:{}, filePath:{}", bean.getFileName(), bean.getFilePath());
                        e.printStackTrace();
                    }
                });
            }
        } catch (MessagingException e) {
            log.error("==邮件发送失败", e);
            return Result.error("邮件发送失败");
        }
        try {
            javaMailSender.send(mimeMessage);
            log.info("==邮件发送成功, Subject: {}, setTo:{}", emailBean.getSubject(), emailBean.getToEmail());
            return Result.ok();
        } catch (Exception e) {
            log.error("==邮件发送失败", e);
        }
        return Result.error("邮件发送失败");
    }

    /**
     * 发送一封嵌入静态资源的邮件
     * @param emailBean 文件内容
     * @return
     */
    public Result sendInlineMail(EmailBean emailBean) {
        log.info("==开始发送邮件, Subject: {}, setTo:{}", emailBean.getSubject(), emailBean.getToEmail());
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper helper;
        try {
            helper = new MimeMessageHelper(mimeMessage, true);
            helper.setFrom(emailBean.getFromEmail());
            helper.setTo(emailBean.getToEmail());
            helper.setSubject(emailBean.getSubject());
            helper.setText(emailBean.getText(), true);
            // 注意addInline()中资源名称 hello 必须与 text正文中cid:hello对应起来
            FileSystemResource file = new FileSystemResource(new File(emailBean.getInlineFile().getFilePath()));
            helper.addInline(emailBean.getInlineFile().getContentId(), file);
        } catch (MessagingException e) {
            log.error("==邮件发送失败", e);
            return Result.error("邮件发送失败");
        }
        try {
            javaMailSender.send(mimeMessage);
            log.info("==邮件发送成功, Subject: {}, setTo:{}", emailBean.getSubject(), emailBean.getToEmail());
            return Result.ok();
        } catch (Exception e) {
            log.error("==邮件发送失败", e);
        }
        return Result.error("邮件发送失败");
    }

    /**
     * 发送一封模板邮件
     * @param emailBean 文件内容
     * @return
     */
    public Result sendTemplateMail(EmailBean emailBean) {
        log.info("==开始发送邮件, Subject: {}, setTo:{}", emailBean.getSubject(), emailBean.getToEmail());
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper helper;
        try {
            helper = new MimeMessageHelper(mimeMessage, true);
            helper.setFrom(emailBean.getFromEmail());
            helper.setTo(emailBean.getToEmail());
            helper.setSubject(emailBean.getSubject());
            helper.setText(emailBean.getText(), true);
        } catch (MessagingException e) {
            log.error("==邮件发送失败", e);
            return Result.error("邮件发送失败");
        }
        try {
            javaMailSender.send(mimeMessage);
            log.info("==邮件发送成功, Subject: {}, setTo:{}", emailBean.getSubject(), emailBean.getToEmail());
            return Result.ok();
        } catch (Exception e) {
            log.error("==邮件发送失败", e);
        }
        return Result.error("邮件发送失败");
    }

}
